/**
 * 
 */
package com.aaron.server;

import com.aaron.client.User;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.io.*;


/**
 * @author aaron
 *
 */
final class SerializableUser implements Serializable{
	static final long serialVersionUID=1;
	private String name;
	//private ArrayList contacts;
	private String auth;
	public SerializableUser(String name, ArrayList contacts, String auth){
		this.name=name;
		//this.contacts=contacts;
		this.auth=auth;
	}
	public SerializableUser(){
		
	}
	public String getName(){
		return this.name;
	}
	public ArrayList getContacts(){
		return new ArrayList();//this.contacts;
	}
	public String getAuth(){
		return this.auth;
	}

	public void setName(String name){
		this.name=name;
	}
	public void setContacts(ArrayList contacts){
		//this.contacts=contacts;
	}
	public void setAuth(String auth){
		this.auth=auth;
	}
}
public class UserCacheServer {
	
	private Connection con;
	public UserCacheServer()throws DatabaseException{
		try{
			String username="aaron";
			String password="li!insin";
			String url = "jdbc:mysql://localhost/VivCode";
			Class.forName ("com.mysql.jdbc.Driver").newInstance();
			con = DriverManager.getConnection (url, username, password);
		}
		catch(ClassNotFoundException e){
			System.err.println ("ClassNotFoundException "+e.getMessage());
			throw new DatabaseException(e.getMessage());
		}
		catch(InstantiationException e){
			System.err.println ("InstantiationException "+e.getMessage());
			throw new DatabaseException(e.getMessage());
		}
		catch(IllegalAccessException e){
			System.err.println ("IllegalAccessException "+e.getMessage());
			throw new DatabaseException(e.getMessage());
		}
		catch(SQLException e){
			System.err.println ("SQLException "+e.getMessage());
			throw new DatabaseException(e.getMessage());
		}
		System.out.println ("Database connection established");
	}
	public void cacheUser(String auth, User user){
		try{
			//check for any previous session
			String sql="SELECT COUNT(*) FROM `UserCache` WHERE `auth` = '"+auth+"' LIMIT 1;";
			Statement stmt = con.createStatement();
			//if previous session found, delete it
			ResultSet rs=stmt.executeQuery(sql);
			rs.next();
			if(rs.getInt(1)!=0){
				Statement delete_stmt = con.createStatement();
				sql="DELETE FROM `UserCache` WHERE `auth` = '"+auth+"' LIMIT 1;";
				delete_stmt.executeUpdate(sql);
			}
			
			//create new session
			PreparedStatement insertUser = con.prepareStatement(
					"INSERT INTO `UserCache` ( `auth` , `user` ) VALUES ('"+auth+"', ?);");
			SerializableUser suser=new SerializableUser(user.getName(), user.getContacts(), user.getAuth());
			
			ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
			ObjectOutputStream out = new ObjectOutputStream(bos) ;
	        out.writeObject(suser);
	        out.close();
	    
	        // Get the bytes of the serialized object
	        byte[] buf = bos.toByteArray();
	        insertUser.setBytes(1, buf);
			insertUser.execute();
		}
		catch(SQLException e){
			System.err.println ("cacheUser:SQLException "+e.getMessage());
		}
		catch(IOException e){
			System.err.println("cacheUser: IOException "+e.getMessage());
		}
	}
	
	public User getUser(String auth){
		try{
			String sql="SELECT `user` FROM `UserCache` WHERE `auth` = '"+auth+"' LIMIT 1;";

			Statement stmt = con.createStatement();
			ResultSet rs=stmt.executeQuery(sql);
			if(rs.next()){
				byte[] bytes=(byte[])rs.getObject("user");
				ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
				Object object=in.readObject();
				System.err.println("UserCacheServer.getUser():object type:"+object.getClass().getCanonicalName());
				SerializableUser suser=(SerializableUser)object;
				
				System.err.println("getUser: got user: "+suser.getName());
				return new User(suser.getName(), suser.getContacts(), suser.getAuth());
			}
			else{
				System.err.println("getUser: no user found");
				return new User("Error", new ArrayList(), "Error");
			}
		}
		catch(SQLException e){
			System.err.println("getUser: SQLException "+e.getMessage());
			return new User("Error", new ArrayList(), "Error");
		}
		catch(ClassCastException e){
			System.err.println("getUser: ClassCastException "+e.getMessage());
			return new User("Error", new ArrayList(), "Error");
		}
		catch(ClassNotFoundException e){
			System.err.println("getUser: ClassNotFoundException "+e.getMessage());
			return new User("Error", new ArrayList(), "Error");
		}
		catch(IOException e){
			System.err.println("getUser: IOException "+e.getMessage());
			return new User("Error", new ArrayList(), "Error");
		}
	}
}
